/*
 * Copyright 2011-2012 by The Regents of the University of California Licensed
 * under the Apache License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License. you may obtain a copy of the
 * License from
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package edu.ucsd.db.bassarisk.storage.columns;

import java.nio.ByteBuffer;

import edu.ucsd.db.bassarisk.data.api.IValueType.ITypeTools;
import edu.ucsd.db.bassarisk.data.values.IntType;
import edu.ucsd.db.bassarisk.data.values.IntType.IntTools;
import edu.ucsd.db.bassarisk.storage.common.ColumnStore;
import edu.ucsd.db.bassarisk.storage.loading.CabinetLoader;
import edu.ucsd.db.bassarisk.storage.loading.ColumnLoader;
import edu.ucsd.db.bassarisk.storage.loading.ColumnSegmentInfo;
import edu.ucsd.db.bassarisk.storage.loading.DrawerLoader;
import edu.ucsd.db.bassarisk.storage.loading.FixedLengthAscendingIntegerColumnIndexer;
import edu.ucsd.db.bassarisk.storage.loading.FixedLengthAscendingIntegerDrawerIndexer;
import edu.ucsd.db.bassarisk.storage.loading.FixedLengthIntegerCardLoader;
import edu.ucsd.db.bassarisk.storage.loading.ICardLoader;
import edu.ucsd.db.bassarisk.storage.loading.IColumnIndexer;
import edu.ucsd.db.bassarisk.storage.loading.IDrawerIndexer;
import edu.ucsd.db.bassarisk.storage.reading.CabinetReader;
import edu.ucsd.db.bassarisk.storage.reading.ColumnReader;
import edu.ucsd.db.bassarisk.storage.reading.DrawerReader;
import edu.ucsd.db.bassarisk.storage.reading.FixedLengthAscendingIntegerColumnIndexReader;
import edu.ucsd.db.bassarisk.storage.reading.FixedLengthAscendingIntegerDrawerIndexReader;
import edu.ucsd.db.bassarisk.storage.reading.FixedLengthIntegerCardReader;
import edu.ucsd.db.bassarisk.storage.reading.ICardReader;
import edu.ucsd.db.bassarisk.storage.reading.IColumnIndexReader;
import edu.ucsd.db.bassarisk.storage.reading.IDrawerIndexReader;

public class FixedLengthAscendingIntegerColumnFactory implements
    IColumnFactory<IntType> {

  @Override
  public ColumnLoader<IntType> makeColumnLoader(final CabinetLoader cabinetLoader,
                                                final String columnKey) {
    ITypeTools<IntType> columnTools = IntTools.INSTANCE;
    // Prepare injected dependencies
    ICardLoader<IntType> cardLoader = new FixedLengthIntegerCardLoader();
    ByteBuffer drawerBuffer = ByteBuffer.allocate(ColumnStore.BYTES_IN_DRAWER);
    IDrawerIndexer<IntType> drawerIndexer =
        new FixedLengthAscendingIntegerDrawerIndexer();
    ColumnSegmentInfo<IntType> drawerInfo =
        new ColumnSegmentInfo<IntType>(columnTools);
    DrawerLoader<IntType> drawerLoader =
        new DrawerLoader<IntType>(drawerIndexer, drawerInfo, drawerBuffer);
    IColumnIndexer<IntType> columnIndexer =
        new FixedLengthAscendingIntegerColumnIndexer();
    ColumnSegmentInfo<IntType> columnInfo =
        new ColumnSegmentInfo<IntType>(columnTools);

    // Create loader
    ColumnLoader<IntType> cLoader =
        new ColumnLoader<IntType>(cabinetLoader, cardLoader, drawerLoader,
                                  columnIndexer, columnInfo, columnKey);
    return cLoader;
  }

  @Override
  public ColumnReader<IntType> makeColumnReader(final CabinetReader cabinetReader,
                                                final int columnHeaderAddress) {
    ITypeTools<IntType> columnTools = IntTools.INSTANCE;
    // Prepare injected dependencies
    ICardReader<IntType> cardReader = new FixedLengthIntegerCardReader();
    IDrawerIndexReader<IntType> drawerIndexReader =
        new FixedLengthAscendingIntegerDrawerIndexReader();
    DrawerReader<IntType> drawerReader =
        new DrawerReader<IntType>(cardReader, drawerIndexReader, columnTools);
    IColumnIndexReader<IntType> columnIndexReader =
        new FixedLengthAscendingIntegerColumnIndexReader();

    // Create reader
    ColumnReader<IntType> cReader =
        new ColumnReader<IntType>(drawerReader, columnIndexReader, columnTools);
    cReader.initialize(cabinetReader, columnHeaderAddress, columnTools);
    return cReader;
  }

}
